package cn.com.dnt.jmxmonitor.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.Scanner;

import cn.com.dnt.jmxmonitor.entity.JMXEntity;
import cn.com.dnt.jmxmonitor.handler.JMXCall;
import cn.com.dnt.jmxmonitor.handler.JVMThreadExtractor;
import cn.com.dnt.jmxmonitor.handler.JVMThreadExtractor.ThreadInfo;
import cn.com.dnt.jmxmonitor.handler.ProxyClient;
import cn.com.dnt.jmxmonitor.util.JSONUtil;

public class JMXSocketServer {

	public static final int port = 8888;// 监听的端口号

	public static void main(String[] args) throws Exception {
		System.out.println("server start...\n");
		JMXSocketServer server = new JMXSocketServer();
		server.init();
	}

	public void init() {
		String envValue = System.getenv("JMX_MONITOR_PORT");
		String sysValue = System.getProperty("jmx.monitor.port");
		// 暴露监听端口
		int monitorPort = port;
		if (sysValue != null) {
			monitorPort = Integer.parseInt(sysValue);
		} else if (envValue != null) {
			monitorPort = Integer.parseInt(envValue);
		}
		System.out.println("start SocketServer port:" + monitorPort + "...\n");
		try {
			ServerSocket serverSocket = new ServerSocket(monitorPort);
			while (true) {
				// 一旦有堵塞, 则表示服务器与客户端获得了连接
				Socket client = serverSocket.accept();
				// 处理这次连接
				new HandlerThread(client);
			}
		} catch (Exception e) {
			System.out.println("server error: " + e.getMessage());
		}
	}

	private class HandlerThread implements Runnable {
		private Socket socket;

		public HandlerThread(Socket client) {
			socket = client;
			new Thread(this).start();
		}

		public void run() {
			try {
				System.out.println("client in...");
				InputStream inStream = socket.getInputStream();
				OutputStream outStream = socket.getOutputStream();
				Scanner in = new Scanner(inStream);
				PrintWriter out = new PrintWriter(outStream, true);
				out.print("Hello,gay!Enter BYE to exit.");
				boolean done = false;
				while (!done && in.hasNextLine()) {
					String line = in.nextLine();
					if (line.trim().equals("BYE")) {
						done = true;
					} else {
						String resJson = getThreadNum(line);
						out.print(resJson);
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (socket != null) {
					try {
						if (!socket.isClosed()) {
							socket.close();
						}
						System.out.println("client out...");
					} catch (Exception e) {
						socket = null;
						System.out.println("server finally error:" + e.getMessage());
					}
				}
			}
		}
	}

	private static String getThreadNum(String reqJson) {
		List<JMXEntity> resList = JSONUtil.json2list(reqJson, JMXEntity.class);
		for (JMXEntity entity : resList) {
			String hostName = entity.getHost();
			int jmxPort = entity.getPort();
			// 从JMX中获取JVM信息
			ProxyClient proxyClient = null;
			try {
				proxyClient = ProxyClient.getProxyClient(hostName, jmxPort, null, null);
				proxyClient.connect();
				JMXCall<ThreadInfo> threadExtractor = new JVMThreadExtractor(proxyClient, jmxPort);
				ThreadInfo threadInfo = threadExtractor.call();
				entity.setThreadnum(threadInfo.getThreadNum());
				entity.setPeakthreadnum(threadInfo.getPeakThreadNum());
			} catch (Exception e) {
				continue;
			} finally {
				if (proxyClient != null) {
					proxyClient.disconnect();
				}
			}
		}
		return JSONUtil.obj2json(resList);
	}
}
